<template>
  <div id="image-container">
    <div id="image-box" ref="imageBox" v-image-zoom
         :style="{backgroundImage: `url(${imgUrl})`, cursor: mode === 2 ? 'crosshair' : 'default'}">
      <div v-for="(mark, index) in markList" :key="mark.id" class="mark"
           :style="{ top: `${mark.y}px`, left: `${mark.x}px` }"
           :class="{ 'selected' : focusOn === mark.number }"
           @click.stop="focusMark(mark, $event)"
           @click.right="removeMark(mark)"
           @mousedown="startDrag(mark, $event)">
        <el-tooltip placement="bottom" width="20" effect="light"
                    :disabled="mark.text.length === 0">
          <span style="white-space: pre-wrap" slot="content" v-html="mark.text"></span>
          <span>{{ index + 1 }}</span>
        </el-tooltip>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'imageZoom',
  props: ["markList", 'mode', 'focusOn', 'imgUrl'],
  data() {
    return {
      transformData: {
        scale: 1,  // 缩放比例
        rotate: 0,  // 旋转角度
        offsetX: 0, // 位移x
        offsetY: 0, // 位移y
        isMouseDown: false,  // 是否移动
        initialX: 0,  // 初始x
        initialY: 0,  // 初始y
      },  // 图片数据
      clickMarkData: {
        x: 0,
        y: 0
      }
    }
  },

  methods: {
    /**
     * 添加标记
     * @param x x坐标
     * @param y y坐标
     */
    addMark(x, y) {
      let obj = {
        number: this.markList[this.markList.length - 1]?.number + 1 || 1,
        text: '',
        textAmend: '',
        x: x.toFixed(0),
        y: y.toFixed(0)
      }
      this.$emit('addMark', obj)
    },
    /**
     * 删除标记
     * @param mark 删除标记
     */
    removeMark(mark) {
      if (this.mode === 2 || this.mode === 5) {
        this.$emit('removeMark', mark)
      }
    },
    /**
     * 聚焦标记
     * @param mark 标记
     */
    focusMark(mark) {
      this.$emit('focusMark', mark)
    },
    /**
     * 开始拖拽
     * @param mark
     * @param event
     */
    startDrag(mark, event) {
      if (this.mode !== 5) {
        return
      }
      let that = this

      // 阻止默认事件，避免选中文本或其他元素
      event.preventDefault();

      // 记录初始鼠标位置和标记位置
      const initialMouseX = event.clientX;
      const initialMouseY = event.clientY;
      let initialMarkX = Number(mark.x);
      let initialMarkY = Number(mark.y);

      // 添加事件监听器
      document.addEventListener('mousemove', onMouseMove);
      document.addEventListener('mouseup', onMouseUp);

      // 鼠标移动时的事件处理程序
      function onMouseMove(event) {
        // 计算鼠标移动距离
        const deltaX = event.clientX - initialMouseX;
        const deltaY = event.clientY - initialMouseY;

        // 更新标记位置
        mark.x = initialMarkX + Number(deltaX);
        mark.y = initialMarkY + Number(deltaY);
      }

      // 鼠标松开时的事件处理程序
      function onMouseUp() {
        // 移除事件监听器
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);

        // 在拖拽结束时通知父组件更新标记
        that.$emit('updateMark')
      }
    },
    /**
     * 初始化位置
     */
    initImg() {
      this.transformData = {
        scale: 1,  // 缩放比例
        rotate: 0,  // 旋转角度
        offsetX: 0, // 位移x
        offsetY: 0, // 位移y
        isMouseDown: false,  // 是否移动
        initialX: 0,  // 初始x
        initialY: 0,  // 初始y
      }
      let el = document.getElementById('image-box');
      el.style.transform = 'scale(1, 1)'
      el.style.left = '0'
      el.style.top = '0'
    }
  },
  mounted() {
    // 禁用浏览器鼠标右键
    document.oncontextmenu = new Function('event.returnValue=false');
  },

  directives: {
    'image-zoom': {
      bind(el, binding, vnode) {
        el.addEventListener('wheel', (event) => {
          event.preventDefault();
          const delta = Math.sign(event.deltaY); // 获取鼠标滚轮方向，1 表示向下滚动，-1 表示向上滚动

          let scale = vnode.context.transformData.scale - delta * 0.1; // 根据需要调整缩放速度
          scale = Math.max(0.5, scale); // 设置最小缩放值，避免缩放过小
          scale = Math.min(1.5, scale); // 设置最小缩放值，避免缩放过小
          vnode.context.transformData.scale = scale
          el.style.transform = `scale(${scale}, ${scale})`;
        })

        el.addEventListener('mousedown', mousedownHandle, false);

        // 鼠标按下事件
        function mousedownHandle(e) {
          // 阻止默认事件，避免选中文本或其他元素
          e.preventDefault();

          if (e.target === el) {
            vnode.context.transformData.initialX = e.clientX - el.offsetLeft;
            vnode.context.transformData.initialY = e.clientY - el.offsetTop;
            vnode.context.transformData.isMouseDown = true;
          }

          // 左键新增
          if (vnode.context.mode === 2 && e.button === 0) {
            let x = e.offsetX - 10
            let y = e.offsetY - 10
            vnode.context.addMark(x, y)
          }

          if (vnode.context.mode !== 2) {
            document.addEventListener('mousemove', mousemoveHandle, false);
          }

          document.addEventListener('mouseup', mouseupHandle, false);
        }

        // 鼠标移动事件
        function mousemoveHandle(e) {
          if (vnode.context.transformData.isMouseDown) {
            e.preventDefault();

            document.getElementById('image-box').style.cursor = 'move'  // 鼠标样式
            vnode.context.transformData.offsetX = e.clientX - vnode.context.transformData.initialX;
            vnode.context.transformData.offsetY = e.clientY - vnode.context.transformData.initialY;
            el.style.left = vnode.context.transformData.offsetX + 'px';
            el.style.top = vnode.context.transformData.offsetY + 'px';
          }
        }

        // 鼠标抬起事件
        function mouseupHandle() {
          vnode.context.transformData.isMouseDown = false;
          vnode.context.transformData.initialX = vnode.context.transformData.offsetX;
          vnode.context.transformData.initialY = vnode.context.transformData.offsetY;
          document.removeEventListener('mousemove', mousemoveHandle)
          // 当模式为标记模式则不还原鼠标样式
          if (vnode.context.mode !== 2) {
            document.getElementById('image-box').style.cursor = 'default'  // 鼠标样式
          }
        }
      }
    }
  }
}
</script>

<style scoped lang="scss">
#image-container {
  width: 100%;
  height: 100%;
  border-radius: 5px;
  overflow: hidden !important;
  position: relative;

  #image-box{
    position: relative;
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    border-radius: 5px;
  }
  .mark {
    position: absolute;
    min-width: 15px;
    min-height: 15px;
    border-radius: 50%;
    background-color: hotpink;
    font-size: 11px;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content:center;
    z-index: 99;
    cursor: pointer;
    opacity: 0.6;
  }
  .selected {
    background-color: #409EFF;
  }
}
</style>